package com.thinking.in.spring.ioc.dependency.injection;

import com.think.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;
import java.util.Set;

/**
 * 延迟的以来注入：
 *      ObjectFactory :
 *
 *      ObjectProvider:
 *
 * @author zjiajia
 * @date 2021/12/31 13:17
 */
public class LazyAnnotationDependencyInjectionDemo {

    @Autowired
    @Qualifier("user")
    private User user;
    /**
     * 延迟注入 ：非安全
     */
    @Autowired
    private ObjectFactory<Set<User>> userObjectFactory;
    /**
     * 延迟注入  ，安全
     */
    @Autowired
    private ObjectProvider<User> userObjectProvider;


    public static void main(String[] args) {
        // 创建 BeanFactory
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

        // xml Bean定义信息 Reader
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        // 加载配置信息  ，解析 装载 配置文件
        xmlBeanDefinitionReader.loadBeanDefinitions("classpath:/META-INF/dependency-lookup-context.xml");

        // 注册 configuration Class (配置类)
        applicationContext.register(LazyAnnotationDependencyInjectionDemo.class);

        // 启动Spring 应用上下文
        applicationContext.refresh();

        LazyAnnotationDependencyInjectionDemo demo = applicationContext.getBean(LazyAnnotationDependencyInjectionDemo.class);


        System.out.println("user : " +  demo.user);
        System.out.println("user " +  demo.userObjectFactory.getObject());

        System.out.println("user : " + demo.userObjectProvider.getObject());




        // 关闭应用上下文
        applicationContext.close();


    }

    /**
     * 注解的形式 ： 首先拿到 UserHolder Bean
     *      让后将 User 作为参数传入
     * @param user      user
     * @return          userHolder
     */
    @Bean
    public UserHolder userHolder(User user){

        return new UserHolder(user);
    }
}
